/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.zh.rxharmony;

import com.zh.rxharmony.schedulers.HarmonySchedulers;
import io.reactivex.disposables.Disposable;
import ohos.eventhandler.EventRunner;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 主线程Disposable实现类，一般配合RxBinding使用
 */
public abstract class MainThreadDisposable implements Disposable {
    //工具方法，可以检查是否是主线程，非主线程会抛出一个IllegalStateException异常
    public static void verifyMainThread() {
        if (EventRunner.current() != EventRunner.getMainEventRunner()) {
            throw new IllegalStateException(
                "Expected to be called on the main thread but was " + Thread.currentThread().getName());
        }
    }

    //原子变量，保证多线程安全
    private final AtomicBoolean unsubscribed = new AtomicBoolean();

    @Override
    public final boolean isDisposed() {
        //返回是否切换
        return unsubscribed.get();
    }

    @Override
    public final void dispose() {
        //被切断，确保只能切断一次，原子标志只能设置一次，从false变true
        if (unsubscribed.compareAndSet(false, true)) {
            //主线程，直接切断，非主线程则通过主线程调度器发送任务进行切断
            if (EventRunner.current() == EventRunner.getMainEventRunner()) {
                onDispose();
            } else {
                //非主线程，通过调度器，在主线程中切断
                HarmonySchedulers.mainThread().scheduleDirect(this::onDispose);
            }
        }
    }

    protected abstract void onDispose();
}
